#include <stdio.h>
#include "ohos_init.h"
#include "los_mux.h"
#include "los_task.h"
#include "cmsis_os2.h"

osMutexId_t g_testMux;
osThreadId_t g_testTaskId01;
osThreadId_t g_testTaskId02;

const osMutexAttr_t mutex_attr = {
    .name = "testMutex",
    .attr_bits = osMutexRecursive | osMutexPrioInherit,
};

void Example_MutexTask1(void *argument)
{
    osStatus_t ret;
    
    printf("task1 try to get mutex, wait 10 ticks.\n");
    ret = osMutexAcquire(g_testMux, 10);  
    
    if (ret == osOK) {
        printf("task1 get mutex g_testMux.\n");
        osMutexRelease(g_testMux);
    } else if (ret == osErrorTimeout) {
        printf("task1 timeout and try to get mutex, wait forever.\n");
        ret = osMutexAcquire(g_testMux, osWaitForever); 
        if (ret == osOK) {
            printf("task1 wait forever, get mutex g_testMux.\n");
            osMutexRelease(g_testMux);
        }
    }
}

void Example_MutexTask2(void *argument)
{
    printf("task2 try to get mutex, wait forever.\n");
    osMutexAcquire(g_testMux, osWaitForever);  
    
    printf("task2 get mutex g_testMux and suspend 100 ticks.\n");
    osDelay(100); 
    
    printf("task2 resumed and post the g_testMux\n");
    osMutexRelease(g_testMux);
}

void Example_TaskEntry(void)
{
    
    const osThreadAttr_t task1_attr = {
        .name = "MutexTsk1",
        .stack_size = 0x1000,
        .priority = osPriorityNormal1
    };
    
    const osThreadAttr_t task2_attr = {
        .name = "MutexTsk2",
        .stack_size = 0x1000,
        .priority = osPriorityNormal2
    };

    g_testMux = osMutexNew(&mutex_attr);
    osKernelLock();
    g_testTaskId01 = osThreadNew(Example_MutexTask1, NULL, &task1_attr);
    g_testTaskId02 = osThreadNew(Example_MutexTask2, NULL, &task2_attr);
    osKernelUnlock();
    osDelay(300);  
    
    osMutexDelete(g_testMux);
    osThreadTerminate(g_testTaskId01);
    osThreadTerminate(g_testTaskId02);
}

APP_FEATURE_INIT(Example_TaskEntry);